跳到主要内容

调优和故障排除

本主题提供 GBase 8s JDBC Driver 的调优和故障排除信息。

调试 JDBC API 程序

可以设置 SQLIDEBUG 连接属性来生成二进制协议跟踪。设置连接属性 SQLIDEBUG 来指定一个文件。例如:

SQLIDEBUG=C:\\tmp\\gbasedbtjdbctrace

为每个连接生成一个新的跟踪文件,其后缀为时间戳。如果您正在使用 IfxDataSource接口,则可以使用 IfxDataSource.setIfxSQLIDEBUG (String fname) 方法。JDBC jar 文件的调试版本不包含在 GBase 8s JDBC Driver Version 3.00.JC1 或更高的版本中。

重要

二进制 SQLI 协议跟踪功能(SQLIDEBUG)只能在 GBase 技术支持指导下使用。

管理性能

本节描述了可能影响查询性能的问题:

  • FET_BUF_SIZE 和 BIG_FET_BUF_SIZE 环境变量
  • 大对象的内存管理
  • 减少网络流量
  • 使用批量插入
  • 调整连接池

管理访存缓冲区大小

使用 FET_BUF_SIZE 和SRV_FET_BUF_SIZE 环境变量设置访存缓冲区的大小。

将 SELECT 语句从 Java™ 程序发送到 GBase 8s 数据库时,返回的行或元组将存储在 GBase 8s JDBC Driver 中的元组缓冲区中。元组缓冲区的缺省大小为返回的元组的大小或 4096 字节。

可以使用 GBase 8s FET_BUF_SIZE 环境变量重写元组缓冲区的缺省大小。FET_BUF_SIZE 可以设置为任何小于等于 2 GiB(2147483648)的正整数。如果设置了FET_BUF_SIZE 环境变量,则它的值应大于缺省元组缓冲区大小,元组缓冲区大小设置为 FET_BUF_SIZE 的值。

同样,您可以使用 SRV_FET_BUF_SIZE 环境变量设置本地数据库服务器参与跨服务器分布式 DML 事务时使用的访存缓冲区的大小。SRV_FET_BUF_SIZE 的最大大小可设置为 1048576(= 1 MiB)。

增加访存缓冲区的大小可以减少 Java™ 程序和数据库之间的网络流量,还会提高查询性能。然而,有时候,增加访存缓冲区的大小实际上会降低查询的性能。如果您的 Java 查询具有多个活动的到数据库的连接或者计算机上的交换空间有限,则可能会发生这种情况。如果 Java 程序或计算机属于这种情况,则可能不希望使用FET_BUF_SIZE 或 SRV_FET_BUF_SIZE 环境变量增加访存缓冲区的大小。

有关设置 GBase 8s 环境变量的更多信息,请参阅连接至数据库。有关增加访存缓冲区大小的更多信息,请参阅《GBase 8s SQL 指南:参考》。

大对象的内存管理

无论何时从数据库服务器访存一个大对象(BYTE 、TEXT 、BLOB 或 CLOB 数据类型),该数据会高速缓存到内存或存储到临时文件(如果它超出内存缓冲区)。如果 JDBC 小程序尝试在本地计算机上创建临时文件,则可能会导致安全性问题。在这种情况下,整个大对象必须存储在内存中。

可以使用 LOBCACHE环境变量来指定存储在连接属性列表中的大对象数据的大小,如下所示:

  • 要设置分配给内存的最大字节数来保存数据,请将 LOBCACHE 值设置为该字节数。

    如果数据大小超出 LOBCACHE 值,则数据会存储在临时文件中。如果在创建此文件期间发生安全违规,则此数据会存储到内存中。

  • 要始终将数据存储在文件中,请将 LOBCACHE 值设置为 0。

    在这种情况中,如果发生安全违规,则 GBase 8s JDBC Driver 不会尝试将数据存储在内存中。未签名的小程序不支持该设置。有关更多信息,请参阅在 applet 中使用驱动程序。

  • 要始终在内存中存储数据。请将 LOBCACHE 值设置为负数。

    如果所需内存量超出,则 GBase 8s JDBC Driver 抛出 SQLException 消息 Out of Memory。

如果 LOBCACHE 值无效或未定义,则缺省大小为 4096。

可以通过数据库 URL 设置LOBCACHE 值,如下所示:

URL = jdbc:gbasedbt-sqli://158.58.9.37:7110/test:user=guest;
password=iamaguest;gbasedbtserver=oltapshm;
lobcache=4096";

上一示例中,如果大对象大小为 4096 字节或更小,则在内存中存储大对象。如果大对象超出 4096 字节,则 GBase 8s JDBC Driver 会试图创建一个临时文件。如果发生安全隔离,则会为整个大对象分配内存。如果失败,则驱动程序抛出 SQLException 消息。

另一示例为:

URL = "jdbc:gbasedbt-sqli://icarus:7110/testdb:
user=guest:passwd=whoknows;gbasedbtserver=olserv01;lobcache=0";

上述示例使用临时文件存储访存的大对象。

第三个示例如下:

URL = "jdbc:gbasedbt-sqli://icarus:7110/testdb:user=guest:
passwd=whoknows;gbasedbtserver=olserv01;lobcache=-1";

上述示例通常使用内存来存储访存的大对象。

有关如何在 Java™ 程序中使用 TEXT 和 BYTE 数据类型的编程的信息,请参阅BYTE 和 TEXT 数据类型。有关如何在 Java 程序中使用 BLOB 和 CLOB 数据类型编程的信息,请参阅智能大对象数据类型。

减少网络流量

当您关闭StatementResultSet对象时,可以使用环境变量 OPTOFC和 IFX_AUTOFREE 减少网络流量。

将 OPTOFC设置为 1 来指定:如果已在客户端元组缓冲区检索到所有合格的行,则 ResultSet.close() 方法不需要网络。在检索完所有的行后,数据库服务器自动关闭游标。

在调用下一个 ResultSet.next() 方法之前,GBase 8s JDBC Driver 在客户端元组缓冲区中可能有也可能没有附加的行。因此,除非 GBase 8s JDBC Driver 已经从数据库服务器检索到所有的行,否则当 OPTOFC 设置为 1 时,ResultSet.close() 方法可能仍然需要网络往返。

IFX_AUTOFREE设置为 1 以指定如果数据库服务器中的游标已经关闭,则 Statement.close() 方法不需要网络往返来释放数据库服务器游标资源。

还可以使用 setAutoFree(boolean flag) 和 getAutoFree() 方法释放数据库服务器游标资源。有关更多信息,请参阅“自动释放”特性。

当游标关闭后,数据库服务器显式地通过 ResultSet.close()方法或隐式地通过 OPTOFC 环境变量自动释放游标资源。

当游标资源释放后,该游标不能再被引用。

有关如何使用 OPTOFC 和IFX_AUTOFREE 环境变量的示例,请参阅 示例代码文件 中描述的 autofree.java optofc.java 演示示例。在这些示例中,使用 Properties.put() 方法设置变量。

有关 GBase 8s 环境变量的设置的更多信息,请参阅随同 GBase 8s JDBC 驱动程序的 GBase 8s 环境变量。

批量插入

批量插入功能提高了使用多个值设置多次执行的单个 INSERT 语句的性能。有关更多信息,请参阅执行批量插入。

连接池

要提高应用程序的性能和可伸缩性,可以通过引用 ConnectionPoolDataSource 对象的 DataSource 对象获得到数据库服务器的连接。GBase 8s JDBC Driver 提供一个连接池管理器作为 ConnectionPoolDataSource 对象的透明组件。连接池管理器在池中保持一个关闭的连接,而不是将连接关闭返回到数据库服务器。每当用户请求新的连接时,连接池管理器从该池获得连接,从而避免关闭服务器并重新打开连接的开销。

如果应用程序收到频繁的定期连接请求,则使用 ConnectionPoolDataSource 对象可以显著提高性能。

有关如何以及为何使用 DataSource 或 ConnectionPoolDataSource 对象的完整信息,请参阅 JDBC 3.0 API。

重要

此功能不会影响 IfxXAConnectionPoolDataSource,它假设连接池由事务管理器处理。

部署 ConnectionPoolDataSource 对象

请遵循以下步骤:

  • 变量 cpds 引用 ConnectionPoolDataSource 对象。
  • ConnectionPoolDataSource对象的 JNDI 逻辑名称为 myCPDS。
  • 变量ds引用 DataSource对象。
  • DataSource 对象的逻辑名称为 DS_Pool

要部署 ConnectionPoolDataSource 对象:

  1. 实例化 IfxConnectionPoolDataSource 对象。

  2. 对此对象设置任何期望调整的属性:

    cpds.setIfxCPMInitPoolSize(15);
    cpds.setIfxCPMMinPoolSize(2);
    cpds.setIfxCPMMaxPoolSize(20);
    cpds.setIfxCPMServiceInterval(30);
  3. 使用 JNDI 注册 ConnectionPoolDataSource对象,将逻辑名称映射到该对象:

    Context ctx = new InitialContext();
    ctx.bind("myCPDS",cpds);
  4. 实例化 IfxDataSource对象。

  5. 将 DataSource 对象与您为 ConnectionPoolDataSource 对象注册的逻辑名称相关联:

    ds.setDataSourceName("myCPDS",ds);
  6. 使用 JNDI 注册DataSource 对象:

    Context ctx = new InitialContext();
    ctx.bind("DS_Pool",ds);

调整连接池管理器

在部署阶段,您或您的数据库管理员可以通过设置以下任何连接池管理器属性的值来控制连接池在应用程序中的工作方式:

  • IFMX_CPM_INIT_POOLSIZE 允许您指定初始化 ConnectionPoolDataSource 对象和初始化时要为池分配的初始连接数。缺省值为 0。

    如果您的应用程序首次初始化 ConnectionPoolDataSource 对象时需要多个连接,请设置此属性。

    要获得此值,请调用 getIfxCPMInitPoolSize()。

    要设置此值,请调用 setIfxCPMInitPoolSize (int init)。

  • IFMX_CPM_MAX_CONNECTIONS 允许您指定 DataSource 对象可以与服务器同时使用的最大并发物理连接数。

    值 -1 指定了一个无限制的数字。缺省值为 -1。

    要获得此值,请调用 getIfxCPMMaxConnections()。

    要设置此值,请调用 setIfxCPMMaxConnections(int limit)。

  • IFMX_CPM_MIN_POOLSIZE 允许您指定池中要维护的最小连接数。请参阅 IFMX_CPM_MIN_AGELIMIT 参数,以了解在池中保留的最小连接数超过年限时要执行的操作。缺省值为 0。

    要获得此值,请调用 getIfxCPMMinPoolSize()。

    要设置此值,请调用 setIfxCPMMinPoolSize(int min),

  • IFMX_CPM_MAX_POOLSIZE 允许您指定池中要维护的最大连接数。当池到达此大小,所有的连接返回到服务器。缺省值为 50。

    要获得此值,请调用 getIfxCPMMaxPoolSize()。

    要设置此值,请调用 setIfxCPMMaxPoolSize(int max)。

  • IFMX_CPM_AGELIMIT 允许您指定空闲连接保留在空闲连接池中的时间(以秒为单位)。

    缺省值为 -1,这意味着空闲连接将保留直到客户端终止。

    要获得此值,请调用 getIfxCPMAgeLimit()。

    要设置此值,请调用 setIfxCPMAgeLimit(long limit)。

  • IFMX_CPM_MIN_AGELIMIT 允许您指定额外时间(以秒为单位),以确保在未收到连接请求时保留空闲连接池中的连接。

    使用此设置可减少在预期的时间段内没有进行连接请求的池中的资源。值为 0 指示在最小池中没有给予连接额外时间;只要它超出 IFMX_CPM_AGELIMIT,连接就会释放到服务器。

    缺省值为 -1,这意味着在客户端终止之前,会保存最小数量的空闲连接。

    要获得此值,请调用 getIfxCPMMinAgeLimit()。

    要设置此值,请调用 setIfxCPMAgeMinLimit(long limit)。

  • IFMX_CPM_SERVICE_INTERVAL 允许您指定池服务的频率(以毫秒为单位)。

    池服务活动包括添加空闲连接(如果空闲连接数低于最小值)和删除空闲连接。缺省值为 50。

    要获得此值,请调用 getIfxCPMServiceInterval()。

    要设置此值,请调用 setIfxCPMServiceInterval (long interval)。

  • IFMX_CPM_ENABLE_SWITCH_HDRPOOL 允许您指定是否在 HAC 数据库服务器对的主和辅助连接池之间自动切换。

    如果您的应用程序需要使用连接池和高可用数据复制,请设置此属性。缺省值为 false。

    要获得此值,请调用 getIfxCPMSwitchHDRPool()。

    要设置此值,请调用 setIfxCPMSwitchHDRPool(boolean flag)。

其中一些属性与 Sun JDBC 3.0 属性重叠。下表列出了 Sun JDBC 3.0 属性及其等效的 GBase 8s 属性。

Sun JDBC 属性名称GBase 8s 属性名称其它信息
initialPoolSizeIFMX_CPM_INIT_POOLSIZE
maxPoolSizeIFMX_CPM_MAX_POOLSIZE对于 maxPoolSize,0 指示没有最大大小。对于 IFMX_CPM_MAX_POOLSIZE,您必须指定一个值。
minPoolSizeIFMX_CPM_MIN_POOLSIZE
maxIdleTimeIFMX_CPM_AGELIMIT对于 maxIdleTime,0 指定没有时间限制。对于 IFMX_CPM_AGELIMIT, -1 指示没有时间限制。

Sun JDBC 3.0 不支持以下属性:

  • maxStatements
  • propertyCycle

高可用数据复制与连接池

连接池的 GBase 8s JDBC Driver 实现提供了与 HAC 对中数据库服务器进行池连接的功能:

  • 主池包含到 HAC 对中主服务器的连接。
  • 辅助池包含到 HAC 对中辅助服务器的连接。

不需要更改应用程序代码就可以利用 HAC 和连接池。将 IFMX_CPM_ENABLE_SWITCH_HDRPOOL 属性设置为 TRUE 以允许在两个池之间切换。当允许切换时,连接池管理器将验证并激活相应的连接池。

当主服务器失败,连接池管理器激活辅助池。激活辅助池后,连接池管理器将验证池的状态以检查主服务器是否正在运行。如果主服务器正在运行,则连接池管理器会将新连接切换到主服务器,并将活动池设置为主池。

如果 IFMX_CPM_ENABLE_SWITCH_HDRPOOL 设置为 FALSE,则可以通过调用 activateHDRPool_Primary() 或activateHDRPool_Secondary() 方法强制切换到另一个连接池:

public void activateHDRPool_Primary(void) throws SQLException
public void activateHDRPool_Secondary(void) throws SQLException

activateHDRPool_Primary() 方法将主连接池切换为活动的连接池。activateHDRPool_Secondary() 方法将辅助连接池切换为活动的连接池。

可以使用连接池的 isReadOnly() 、isHDREnabled() 和 getHDRtype() 方法(请参阅 检查高可用性辅助服务器的只读状态)。

清除池连接

可以通过设置数据库属性,例如 AUTOCOMMIT 和 TRANSACTION ISOLATION 更改其原始默认属性的连接。当连接关闭时,这些属性恢复为缺省值。但是,在连接返回到池时,池化的连接不自动地恢复为缺省属性。

GBase 8s JDBC Driver 中,您可以调用 scrubConnection() 方法来:

  • 将数据库属性和连接级别属性重新设置为缺省值。
  • 关闭打开的游标和事务。
  • 保留所有的语句。

现在启用应用程序服务器高速缓存这些语句,并且可以在应用程序和会话中使用它来为最终用户应用程序提供更好的性能。

scrubConnection() 方法的签名为:

public void scrubConnection() throws SQLException

以下示例演示如何调用 scrubConnection():

try
{
IfmxConnection conn = (IfmxConnection)myConn;
conn.scrubConnection();
}
catch (SQLException e)
{
e.printStackTrace();
}

以下方法验证是否调用 scrubConnection() 释放所有的语句:

public boolean scrubConnectionReleasesAllStatements()

管理连接

下表对比了 connection.close() 和 scrubConnection() 方法在连接池设置中的不同实现。

连接池状态connection.close() 方法的行为scrubconnection() 方法的行为
没有设置连接池关闭数据库连接,所有相关联的语句对象及其结果集的连接不再有效。将连接返回到缺省状态,保留打开的连接,但是关闭结果集连接。只释放与结果集相关联的连接。
使用 GBase 8s 实现的连接池关闭到数据库的连接并重新打开连接,以关闭与连接对象关联的任何语句,并将连接重置为原始状态,然后连接对象返回到连接池。当新的应用程序请求连接时连接有效。将连接返回到缺省状态,保留所有打开的连接,但是关闭所有的结果集。这里不建议调用此方法。
使用 AppServer 实现的连接池由用户定义的连接池实现将连接返回到缺省状态,保留打开的语句,但是关闭结果集

避免应用程序挂起问题(仅限于 HP-UX)

如果在 HP-UX 服务器上的 JDBC 应用程序挂起,那么请检查 HP-UX 服务器上 PTHREAD_COMPAT_MOD 环境变量的设置。PTHREAD_COMPAT_MODE 环境变量应该设置为 1。此变量告知 pthread 库(libpthread)以 1 X 1 模式而不是 MxN 模式运行。1 X 1 是 HP-UX 上的缺省模式。设置此环境变量应该能解决此挂起问题。